package com.faxsun.web.endpoint;

import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import mblog.core.pojos.User;
import mblog.web.formatter.JsonUtils;
import mtons.modules.pojos.Data;
import mtons.modules.pojos.UserContextHolder;
import mtons.modules.pojos.UserProfile;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.faxsun.core.persist.dao.LiveDao;
import com.faxsun.core.persist.entity.LiveManagerPO;
import com.faxsun.core.persist.entity.LivePO;
import com.faxsun.core.persist.entity.UserPO;
import com.faxsun.core.pojos.enums.AccountType;
import com.faxsun.core.service.LiveAdminService;
import com.faxsun.core.service.UserService;
import com.faxsun.core.service.impl.LiveAdminServiceImpl;
import com.faxsun.web.utils.Response;
import com.faxsun.web.utils.WechatApiUtils;

/**
 * 
 * @author zhilin
 * @since Jun 18, 2015
 */
@Controller
@RequestMapping("/api/v1/live")
public class LiveAdminEndpoint {
	private static final Logger logger = LoggerFactory.getLogger(LiveAdminEndpoint.class);
	@Autowired
	LiveAdminService liveAdminService;

	@Autowired
	private UserService userService;

	@Autowired
	private LiveDao liveDao;

	@Value("${live.ceremony.startdate}")
	private String startDate;

	@Value("${live.ceremony.enddate}")
	private String endDate;

	@Value("${live.url.pattern}")
	private String host;

	@Autowired
	private WechatApiUtils wechatApi;

	/**
	 * 取消禁言
	 * 
	 * @param userId
	 *            ：被禁言用户id
	 * @param liveId
	 *            ：直播id
	 * @return
	 */
	@RequestMapping(value = "/talk/enable/{userId}/{liveId}", method = RequestMethod.GET)
	@ResponseBody
	public Response enableSendMessage(@PathVariable("userId") long userId, @PathVariable("liveId") long liveId) {
		String role = this.checkRole(liveId);
		if (role == null || !role.equals(LiveAdminServiceImpl.Roles.ADMIN.toString())) {
			return Response.build("权限不足!", "failure", null);

		}
		liveAdminService.enableSendMsg(liveId, userId);
		return Response.build("取消禁言成功!", "success", null);
	}

	/**
	 * 禁言
	 * 
	 * @param userId
	 *            ：被禁言的用户
	 * @param liveId
	 *            ：直播id
	 * @return
	 */
	@RequestMapping(value = "/talk/disable/{userId}/{liveId}", method = RequestMethod.GET)
	@ResponseBody
	public Response disableSendMessage(@PathVariable("userId") long userId, @PathVariable("liveId") long liveId,
			HttpServletRequest request) {
		try {
			String role = this.checkRole(liveId);
			if (role == null || !role.equals(LiveAdminServiceImpl.Roles.ADMIN.toString())) {
				return Response.build("权限不足!", "failure", null);

			}
			UserProfile profile = UserContextHolder.getUserProfile();
			if (profile.getId() == userId) {
				return Response.build("不能禁言自己！", "failure", null);
			}
			liveAdminService.disableSendMsg(liveId, userId, profile == null ? 0 : profile.getId());
			return Response.build("禁言成功!", "success", null);
		} catch (Exception e) {
			return Response.build("服务异常！", "error", null);
		}
	}

	/**
	 * 修改直播名
	 * 
	 * <code>
	 * http://www.faxsun.com/api/v1/live/1/rename?name=ces2015
	 * </code>
	 * 
	 * @param name
	 * @return
	 * @deprecated replaced by
	 *             {@link #modifyChannelForLoginedUsers(HttpServletRequest)}
	 */
	@RequestMapping(value = "/{liveId}/rename", method = RequestMethod.GET)
	@ResponseBody
	@Deprecated
	public Response renameLive(@PathVariable("liveId") long liveId, @RequestParam("name") String name) {
		try {
			String role = this.checkRole(liveId);
			if (role == null || !role.equals(LiveAdminServiceImpl.Roles.ADMIN.toString())) {
				return Response.build("权限不足!", "failure", null);

			}
			liveAdminService.updateLiveName(liveId, name);
			return Response.build("修改直播名称成功!", "success", null);
		} catch (DataIntegrityViolationException e) {
			return Response.build("重名，请重新选择直播名称!", "failure", null);
		} catch (Exception e) {
			return Response.build("服务器异常!", "error", null);
		}
	}

	/**
	 * <code>
	 * http://www.faxsun.com/api/v1/live/1/new?topic=football3&start=2015-05-27 16:00:00&end=2015-05-27 15:00:00
	 * </code> 创建直播
	 * 
	 * @param topic
	 * @param starttime
	 * @param endtime
	 * @return
	 * @deprecated replaced by
	 *             {@link #createChannelForLoginedUsers(HttpServletRequest)}
	 */
	@RequestMapping(value = "/{userId}/new", method = RequestMethod.GET)
	@ResponseBody
	@Deprecated
	public Response renameLive(@RequestParam("topic") String topic, @PathVariable("userId") long user,
			@RequestParam("start") String starttime, @RequestParam("end") String endtime) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			UserProfile profile = UserContextHolder.getUserProfile();
			if (profile == null || profile.getId() != user) {
				return Response.build("用户不存在,无法创建直播！", "failure", null);
			}
			Date s = sdf.parse(starttime);
			Date e = sdf.parse(endtime);
			if (s.after(e)) {
				return Response.build("结束时间不能早于开始时间!", "failure", null);

			}
			LivePO live = liveAdminService.save(user, topic, s, e);
			return Response.build("创建直播成功!", "success", live);
		} catch (ParseException pe) {
			// TODO Auto-generated catch block
			// pe.printStackTrace();
			return Response.build(pe.getMessage(), "failure", null);

		} catch (Exception e) {
			// Do nothing
		}
		return Response.build("服务器异常", "failure", null);
	}

	/**
	 * 返回禁言用户列表
	 * 
	 * @param liveId
	 * @return
	 */
	@RequestMapping(value = "/{liveId}/disabled", method = RequestMethod.GET)
	@ResponseBody
	public Response getTalkDisabledUsers(@PathVariable("liveId") long liveId) {
		List<UserProfile> users = liveAdminService.getTalkDisabledUser(liveId);
		return Response.build("禁言用户列表", "success", users);
	}

	private String checkRole(long liveId) {
		UserProfile profile = UserContextHolder.getUserProfile();
		if (profile == null)
			return null;
		LiveManagerPO liveManager = liveAdminService.getLiveManager(profile.getId(), liveId);

		return liveManager == null ? null : liveManager.getManagerRole();
	}

	/**
	 * 微信菜单创建频道。频道名称统一为：XXX的毕业直播,每人仅可创建一个。若已存在，则返回已创建的频道。<br>
	 * 表单参数:
	 * 
	 * <pre>
	 * 	headImage:http://...        头像url
	 * 	unionid:unionid             unionid
	 * 	nickname:songdragon/zkdjfa  昵称，四字节的怎么写。。。。
	 * 	openid:123456zxcvda         openid
	 * </pre>
	 * 
	 * @param request
	 * @return
	 * 
	 * 		<pre>
	 * {
	 *   'code': 0,
	 *   'message': '创建成功',
	 *   'data': {
	 *     'url': 'http://101.231.32.250:13131/faxsun-info/live/broadcast/4',
	 *     'channel': {
	 *       'id': 4,
	 *       'topic': '测试channel',
	 *       'startTime': '2015-07-06',
	 *       'endTime': '2015-08-27',
	 *       'coverImage': null,
	 *       'startTimeString': '2015-07-06 10:40:51',
	 *       'endTimeString': '2015-08-27 11:59:59'
	 *     }
	 *   }
	 * }
	 * 
	 *         </pre>
	 */
	@RequestMapping(value = "/wechatCreate", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
	@ResponseBody
	public Data createChannelForWechatUser(HttpServletRequest request) {

		Data ret = Data.failure("频道创建失败");
		UserPO userPO = transformFromRequest(request);

		UserProfile up = this.userService.findByThirdId(userPO.getThirdLogin(), AccountType.WECHAT);
		if (up == null) {
			// 用户不存在
			up = this.userService.createLocalUser(userPO);
		}

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		try {
			Date s = sdf.parse(startDate);
			Date e = sdf.parse(endDate);
			// 只允许创建一个
			List<LivePO> channels = liveAdminService.getMyLive(up.getId());
			boolean isExisted = false;
			String expectedTopic = up.getName() + "的毕业直播";
			LivePO live = null;
			for (LivePO channel : channels) {

				if (channel.getTopic().equals(expectedTopic)) {
					isExisted = true;
					live = channel;
					break;
				}

			}
			if (isExisted) {
				ret = Data.success("您已创建频道：" + expectedTopic);
			} else {
				live = liveAdminService.save(up.getId(), expectedTopic, s, e);
				ret = Data.success("创建成功");

			}
			String url = MessageFormat.format(this.host, live.getId());
			WechatResponse data = new WechatResponse();
			data.url = url;
			data.channel = live;
			ret.setData(data);

		} catch (ParseException e1) {
			logger.error("", e1);
		}

		return ret;
	}

	/**
	 * 创建频道api，浏览器发送请求到此endpoint，endpoint检查用户是否已登录，若未登录，则为此用户创建新频道。<br>
	 * 表单参数:
	 * 
	 * <pre>
	 * 	title:我的测试直播                   频道名称
	 * 	descripiton:这是个测试直播      描述，限制在200字以内
	 * 	start:2015-07-06 9:58        开始时间,24小时，格式：yyyy-MM-dd HH:mm
	 * 	end:2015-08-29 13:23         结束时间,24小时，格式：yyyy-MM-dd HH:mm
	 *  coverImage: http://image.faxsun.com/...  封面url
	 * </pre>
	 * 
	 * @param request
	 * @return
	 * 
	 * 		<pre>
	 * {
	 *   'code': 0,
	 *   'message': '创建成功',
	 *   'data': {
	 *     'url': 'http://101.231.32.250:13131/faxsun-info/live/broadcast/4',
	 *     'channel': {
	 *       'id': 4,
	 *       'topic': '测试channel',
	 *       'description':'',
	 *       'startTime': '2015-07-06',
	 *       'endTime': '2015-08-27',
	 *       'coverImage': null,
	 *       'startTimeString': '2015-07-06 10:40:51',
	 *       'endTimeString': '2015-08-27 11:59:59'
	 *     }
	 *   }
	 * }
	 *         </pre>
	 */
	@RequestMapping(value = "/channel/create", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
	@ResponseBody
	public Data createChannelForLoginedUsers(HttpServletRequest request) {

		Data ret = Data.failure("频道创建失败");

		LivePO channel = extractChannelFromRequest(request);

		// TODO: 根据request中是否包含userid，查询UserProfile
		UserProfile up = UserContextHolder.getUserProfile();
		if (up == null) {
			// 用户不存在
			ret.setMessage("非法用户访问");
			return ret;
		}

		if (channel == null) {
			ret.setMessage("频道数据错误，请检查频道标题");
			return ret;
		}

		try {
			// 每个人创建的channel title必须不同
			List<LivePO> channels = liveAdminService.getMyLive(up.getId());
			boolean isExisted = false;
			String expectedTopic = channel.getTopic();
			LivePO live = null;
			for (LivePO c : channels) {

				if (c.getTopic().equals(expectedTopic)) {
					isExisted = true;
					live = c;
					break;
				}

			}
			if (isExisted) {
				ret = Data.success("您已创建频道：" + expectedTopic);
			} else {
				live = liveAdminService.save(up.getId(), channel);
				ret = Data.success("创建成功");

			}
			String url = MessageFormat.format(this.host, live.getId());
			WechatResponse data = new WechatResponse();
			data.url = url;
			data.channel = live;
			ret.setData(data);

		} catch (Exception e1) {
			logger.error("", e1);
		}

		return ret;
	}

	@RequestMapping(value = "/channel/modify", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
	@ResponseBody
	public Data modifyChannelForLoginedUsers(HttpServletRequest request) {

		Data ret = Data.failure("频道更新失败");

		LivePO channel = extractChannelFromRequest(request);

		// 频道信息
		if (channel == null) {
			ret.setMessage("频道数据错误，请检查频道标题");
			return ret;
		}

		// TODO: 根据request中是否包含userid，查询UserProfile
		UserProfile up = UserContextHolder.getUserProfile();
		String role = this.checkRole(channel.getId());
		if (role == null || !role.equals(LiveAdminServiceImpl.Roles.ADMIN.toString())) {
			// 用户不存在
			ret.setMessage("非法用户访问");
			return ret;
		}

		try {
			// 每个人创建的channel title必须不同
			List<LivePO> channels = liveAdminService.getMyLive(up.getId());
			boolean isExisted = false;
			String expectedTopic = channel.getTopic();
			LivePO live = null;
			for (LivePO c : channels) {
				// 检查是否有重名
				if (c.getTopic().equals(expectedTopic) && c.getId() != channel.getId()) {
					isExisted = true;
					live = c;
					break;
				}

			}
			// 不能和已有频道重名
			if (isExisted) {
				ret.setMessage("您已创建频道：" + expectedTopic + "。请更换其他频道名称!");
			} else {
				// 未重名，则更新
				LivePO dbChannel = liveDao.get(channel.getId());
				logger.info("Update " + JsonUtils.toJson(dbChannel) + "to " + JsonUtils.toJson(channel));
				live = liveAdminService.save(up.getId(), channel);
				ret = Data.success("更新成功");
				String url = MessageFormat.format(this.host, live.getId());
				WechatResponse data = new WechatResponse();
				data.url = url;
				data.channel = live;
				ret.setData(data);

			}

		} catch (Exception e1) {
			logger.error("", e1);
		}

		return ret;
	}

	/**
	 * 从请求中解析form表单
	 * 
	 * @param request
	 * @return 解析成功，LivePO实体；解析失败，返回null
	 */
	private LivePO extractChannelFromRequest(HttpServletRequest request) {
		LivePO channel = new LivePO();
		try {
			String id = request.getParameter("id");
			if (!StringUtils.isEmpty(id)) {
				try {
					long idLong = Long.parseLong(id);
					channel.setId(idLong);
				} catch (Exception e) {
					logger.error("", e);
					channel.setId(0L);
				}
			}
			// title
			String title = request.getParameter("title");
			if (StringUtils.isEmpty(title)) {
				StringBuffer sb = new StringBuffer();
				try {
					sb.append(UserContextHolder.getUserProfile().getName());
				} catch (Exception e) {
					sb.append("未知用户");
					logger.error("", e);
				}
				sb.append("的直播");
				int count = liveDao.countBySimlarTopic(sb.toString());
				if (count > 0)
					sb.append(count + 1);

				title = sb.toString();

				// return null;
			}
			channel.setTopic(title);
			// cover image
			String coverImage = request.getParameter("coverImage");
			if (!StringUtils.isEmpty(coverImage) && !coverImage.contains("/")) {
				// 可能是media_id，尝试下载
				String imageUrl = wechatApi.getMediaUrl(coverImage);
				if (!StringUtils.isEmpty(imageUrl)) {
					coverImage = imageUrl;
				}
			}
			channel.setCoverImage(coverImage);
			// description
			String description = request.getParameter("description");
			if (description == null) {
				description = "";
			}
			channel.setDescription(description);

			// Date
			String start = request.getParameter("start");
			String end = request.getParameter("end");

			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			Date startDate = null;
			Date endDate = null;
			Date now = new Date(System.currentTimeMillis());
			if (!StringUtils.isEmpty(start)) {
				try {
					startDate = sdf.parse(start);
					if (startDate.before(now)) {
						startDate = now;
					}
				} catch (Exception e) {
					startDate = now;
				}
			} else {
				startDate = now;
			}

			if (!StringUtils.isEmpty(end)) {
				try {
					endDate = sdf.parse(end);
				} catch (Exception e) {
				}
			} else {
				endDate = sdf.parse(this.endDate);
			}

			if (startDate.after(endDate)) {
				endDate = sdf.parse(this.endDate);
			}
			channel.setStartTime(startDate);
			channel.setEndTime(endDate);

			return channel;
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 从request中提取表单信息
	 * 
	 * @param request
	 * @return
	 */
	private UserPO transformFromRequest(HttpServletRequest request) {
		UserPO userPO = new UserPO();
		userPO.setAvatar(request.getParameter("headImage"));
		userPO.setUsername(request.getParameter("unionid"));
		userPO.setName(request.getParameter("nickname"));
		userPO.setThirdLogin(request.getParameter("openid"));
		userPO.setIsLocal(1);
		userPO.setCreated(new Date(System.currentTimeMillis()));
		userPO.setRoleLevel(0);
		userPO.setWechatUnionId(request.getParameter("unionid"));
		return userPO;
	}

	@RequestMapping(value = "/admin/addmanager", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, method = RequestMethod.POST)
	@ResponseBody
	public Data addManager(HttpServletRequest request) {

		String liveid = request.getParameter("channelid");
		String userid = request.getParameter("userid");
		Data ret = Data.failure("添加直播员失败！");

		Long liveId = Long.parseLong(liveid);
		Long userId = Long.parseLong(userid);

		if (liveId > 0L && userId > 0L) {
			// liveId userId 均大于0
			User user = this.userService.get(userId);
			if (user != null) {
				// user存在
				String role = this.checkRole(liveId);

				if (!StringUtils.isEmpty(role) && role.equals("ADMIN")) {
					UserProfile up = UserContextHolder.getUserProfile();
					if (up.getId() == userId) {
						// 当前用户未管理员，将自己添加未直播员，则直接返回，因为管理员权限>直播员权限
					} else {
						// 仅管理员可以添加直播员
						this.liveAdminService.addLiveManager(liveId, userId);
						ret = Data.success("添加直播员成功！");
					}
				}
			}
		}
		return ret;
	}

	@RequestMapping(value = "/admin/removemanager", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
	@ResponseBody
	public Data removeManager(HttpServletRequest request) {

		String liveid = request.getParameter("channelid");
		String userid = request.getParameter("userid");
		Data ret = Data.failure("删除直播员失败！");

		Long liveId = Long.parseLong(liveid);
		Long userId = Long.parseLong(userid);

		if (liveId > 0L && userId > 0L) {
			// liveId userId 均大于0
			User user = this.userService.get(userId);
			if (user != null) {
				// user存在
				String role = this.checkRole(liveId);

				if (!StringUtils.isEmpty(role) && role.equals("ADMIN")) {
					UserProfile up = UserContextHolder.getUserProfile();
					if (up.getId() == userId) {
						// 当前用户为管理员，禁止移除自己
					} else {
						// 仅管理员可以移除直播员
						boolean result = this.liveAdminService.removeManager(liveId, userId);
						if (result)
							ret = Data.success("删除直播员成功！");
					}
				}
			}
		}
		return ret;
	}

}

/**
 * 封装给Wechat的回复
 * 
 * @author songdragon 2015年6月25日
 *
 */
class WechatResponse {
	public String url;
	public LivePO channel;
}
